#!/bin/bash
#set -x
TOP_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )"
CUR_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )"
SUPER_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )/../../.." &> /dev/null && pwd )"

if [ ! -f $SUPER_DIR/.pkgsInstall ] && [ ! -d $CUR_DIR/components ]; then
    echo "Error .pkgsInstall not found and $CUR_DIR/components not exist"
	exit
fi

INSTALL_options=""

source $CUR_DIR/scripts/utils.sh

bash_xc="bash -xc"

install_yq() {
    install_sh=$CUR_DIR/components/yq/yq-install.sh
    if [ ! -f $install_sh ] && [ -f $SUPER_DIR/.pkgsInstall ]; then
        install_sh=$(cat $SUPER_DIR/.pkgsInstall | grep -E "/yq-install.sh")
    fi
    if [ -n "$install_sh" ]; then
        $bash_xc "$install_sh --version=$(sed -n  's/\(^[[:space:]]*[^#]yq: \)\(.*\)/\2/p' $CUR_DIR/config/package-${K8S_version}.yaml)"
    fi
}

install_kubevip() {
    install_sh=$CUR_DIR/components/kube-vip/kube-vip-install.sh
    if [ ! -f $install_sh ] && [ -f $SUPER_DIR/.pkgsInstall ]; then
        install_sh=$(cat $SUPER_DIR/.pkgsInstall | grep -E "/kube-vip-install.sh")
    fi
    if [ -n "$install_sh" ]; then
        $bash_xc "cp -rf ${install_sh%/*} ${K8S_vkeVarPath:-/var/lib/vke}/"
    fi
}

install_pkgs() {
    local global_options="$@"
    local install_sh=""
	
	if [ ! -f "$CUR_DIR/config/download.yaml" ] || [ ! -f $CUR_DIR/config/package-${K8S_version}.yaml ]; then
	    echo "download.yaml or package-${K8S_version}.yaml not found"
		exit
	fi
	
	install_kubevip
    #pkgs=$(awk '/PKGS:/ {flag=1; next} /[A-Z]+:$/ {flag=0} flag && /^[ ]+[^#[ ]+:/ {sub(/:[^#]*$/, "", $1); print $1"="$2}' $CUR_DIR/config/package-${K8S_version}.yaml)
    pkgs=$(yq '.PKGS|keys|.[]' $CUR_DIR/config/package-${K8S_version}.yaml | grep -v "yq" | grep -v "kube-vip")
    # yq < 4.34.1
    #global_vars=$(yq e -o props $CUR_DIR/config/download.yaml | grep -vE "^[[:space:]]*#|^[[:space:]]*$" | awk -F ' = ' '{gsub(/\./, "_", $1); print $1"="$2}')
    # yq >= 4.34.1
    global_vars=$(echo $(yq -o=shell $CUR_DIR/config/download.yaml))
	
    echo "install pkgs:[ $pkgs ]"
    for pkg in ${pkgs[@]}; do
        local options="$global_options"
        local pre_vars="$global_vars"
        local version=$(yq .PKGS.$pkg $CUR_DIR/config/package-${K8S_version}.yaml)
        if [ "$options" != "--clean" ] && [ "$options" != "--rm" ] && [ -n "$version" ] && [ "$version" != "null" ]; then
            options="$options --version=$version"
        elif [ "$options" == "--rm" ]; then
		    case $pkg in
			    ebtables|ethtool|conntrack|yq|jq) continue ;;
			esac
		fi
        
        pyellow "----install $pkg $version"
        install_sh="$CUR_DIR/components/$pkg/${pkg}-install.sh"
        # 先从本地组件中获取安装脚本; 适用于离线安装包构造好之后
        if [ ! -f $install_sh ] && [ -f $SUPER_DIR/.pkgsInstall ]; then
            install_sh=$(cat $SUPER_DIR/.pkgsInstall | grep -E "/${pkg}-install.sh")
        fi
        if [ -n "$install_sh" ]; then
            $bash_xc "$pre_vars $install_sh $options"
        fi
    done
}

# download chart to /var/lib/vke/charts
install_charts() {
    local vkeVarPath=${K8S_vkeVarPath:-/var/lib/vke}
    local var_charts_dir=$K8S_vkeVarPath/charts
    mkdir -p $var_charts_dir
    charts=$(yq '.CHARTS|keys|.[]' $CUR_DIR/config/package-${K8S_version}.yaml)
    global_vars=$(echo $(yq -o=shell $CUR_DIR/config/download.yaml))
    echo "download charts:[ $(echo $charts) ]"
    for chart in ${charts[@]}; do 
		local install_sh=$CUR_DIR/components/charts/$chart/${chart}-install.sh
        local download_dir=""
        local pre_vars="$global_vars"
        local options="--downloadonly"
        local version=$(yq .CHARTS.$chart $CUR_DIR/config/package-${K8S_version}.yaml)        
        pyellow "----download $chart $version"
                
        if [ ! -f $install_sh ]; then
            install_sh=$(cat $SUPER_DIR/.pkgsInstall | grep -E "/$chart/${chart}-install.sh" | grep -v "$CUR_DIR/components/charts/$chart/${chart}-install.sh")
        fi
        if [ -n "$install_sh" ]; then
            $bash_xc "$pre_vars $install_sh $options"
            download_dir=${install_sh%/*}
            cp -rf $download_dir $var_charts_dir/
        fi
    done
}

init_node_config() {
  if [ ! -f $CUR_DIR/config/node.yaml ]; then
      pyellow "Create new configuration file: $CUR_DIR/config/node.yaml"
      cat > $CUR_DIR/config/node.yaml << EOF
NODE:
  mode: $INSTALL_mode
  apiServerIp: $INSTALL_apiServerIp
EOF
  else
     pyellow "Using existing configuration file: $CUR_DIR/config/node.yaml"
     if [ -z "$(cat $CUR_DIR/config/node.yaml | grep "^  apiServerIp: " | awk '{print $2}' )" ] || $INSTALL_setApiServerIp; then
         sed -i "/^  apiServerIp:.*/c\  apiServerIp: $INSTALL_apiServerIp" $CUR_DIR/config/node.yaml
     fi
     if [ -z "$(cat $CUR_DIR/config/node.yaml | grep "^  mode: " | awk '{print $2}' )" ] ; then
         sed -i "/^  mode:.*/c  mode: $INSTALL_mode" $CUR_DIR/config/node.yaml
     fi
  fi
  
  if [ -n "$NODE_vip" ]; then
      yq -i .NODE.vip=\"$NODE_vip\" $CUR_DIR/config/node.yaml
  fi
  	 if [ "true" == "$INSTALL_ha" ]; then
	    vip=$(yq .NODE.vip $CUR_DIR/config/node.yaml)
		if [ "$vip" == "null" ] || [ -z "$vip" ]; then
		    cat $CUR_DIR/config/node.yaml
		    echo "Error: k8s HA(High Availability) enable, but vip(NODE.vip) not set, Please use the command below instead "
			echo "    NODE_vip=a.b.c.d ./k8s-install.sh --ha [other options] "
			exit 1
		fi
	 fi
}

# 使用说明函数
print_usage() {
  echo "Usage: $0 [OPTIONS]"
  echo "Options:"
  echo "  -o|--online             Set installation mode to online"
  echo "  -f|--force              Set installation force to true"
  echo "  -s|--startnow           Set start now to true"
  echo "  -d|--downloadonly       build binary install package"
  echo "  -y|--yes                Automatically input y or yes"
  echo "  --master=<a.b.c.d>      Set the IP address of the master node"
  echo "  --rm|--remove           Uninstall kubernetes software, including docker"
  echo "  --ha                    enable ha mode"
  echo "  -c|--clean              Remove installation package"
  echo "  --help                  Show this help message and exit"
}
# 解析输入参数
parse_args() {
  INSTALL_rm=false
  ARGC=$#

  while [[ $# -gt 0 ]]; do
    key="$1"
    case $key in
      --version=*) K8S_version="${key#*=}" ;;
      -y|--yes) INSTALL_yes=true ;;
      --clean|-c) INSTALL_clean=true ;;
      --downloadonly|-d) INSTALL_downloadOnly=true ;;
      --rm|--remove) INSTALL_rm=true ;;
      -o|--online) INSTALL_online=true ;;
      -f|--force) INSTALL_force=true ;;
      -s|--startnow) INSTALL_startnow=true  ;; 
      --master=*) INSTALL_apiServerIp="${key#*=}"
        INSTALL_setApiServerIp=true
        ;;
      --ha) INSTALL_ha="true" ;;		
      --help)
        print_usage
        exit 0
        ;;
      -*)
        for ((i=1; i<${#key}; i++)); do
          case "${key:$i:1}" in
            o) export INSTALL_online=true ;;
            f) export INSTALL_force=true ;;
            s) export INSTALL_startnow=true ;;
            d) export INSTALL_downloadOnly=true ;; 
            c) export INSTALL_clean=true ;;
            y) export INSTALL_yes=true ;;
            *) print_usage; exit 1 ;;
          esac
        done
        #shift
        ;;
      *)
        print_usage
        exit 1
        ;;
    esac
    shift
  done

  K8S_version=${K8S_version:-1.21.11}
  INSTALL_online=${INSTALL_online:-false}
  INSTALL_force=${INSTALL_force:-false}
  INSTALL_startnow=${INSTALL_startnow:-false}
  INSTALL_downloadOnly=${INSTALL_downloadOnly:-false}
  INSTALL_target=${INSTALL_target:-kubernetes}
  INSTALL_clean=${INSTALL_clean:-false}
  INSTALL_yes=${INSTALL_yes:-false}
  INSTALL_setApiServerIp=${INSTALL_setApiServerIp:-false}
  INSTALL_ha=${INSTALL_ha:-false}
  
  if [ -z "$INSTALL_apiServerIp" ]; then
      INSTALL_apiServerIp=$(get_default_ip)
      INSTALL_mode=create
  else
      local ip_regexp='^((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$'
      if [[ ! $INSTALL_apiServerIp =~ $ip_regexp ]]; then
          echo "Please set the master IP address using the flag --master=<a.b.c.d>"
          exit
      fi
      if check_ip_is_local $INSTALL_apiServerIp; then
         INSTALL_mode=create
      elif ! ping $INSTALL_apiServerIp -c 1 > /dev/null; then
	     INSTALL_mode=create
	  else
         INSTALL_mode=join
      fi
  fi
  
  $INSTALL_force && INSTALL_options="$INSTALL_options --force"
  $INSTALL_downloadOnly && INSTALL_options="$INSTALL_options --downloadonly"
  $INSTALL_online && INSTALL_options="$INSTALL_options --online"

  #删除软件
  if $INSTALL_rm; then
    echo "Remove $INSTALL_target"
    $CUR_DIR/scripts/k8s-stop.sh
    install_pkgs --rm
    exit 0
  fi

  #清空安装包
  if $INSTALL_clean && [ $ARGC -eq 1 ]; then
    install_pkgs --clean
    exit 0
  fi 

  if ! $INSTALL_downloadOnly; then
	  init_node_config
	  cat $CUR_DIR/config/node.yaml
	  if ! $INSTALL_yes ; then
		read -p "Please enter 'yes' or 'y' to continue: " input
		if [[ $input != "yes" && $input != "y" ]]; then
		  echo "Installation aborted"
		  exit 1
		fi
	  fi
  fi
  echo "Install options: "
  echo "  k8sVersion=${K8S_version} force=$INSTALL_force online(apt/yum)=$INSTALL_online startnow=$INSTALL_startnow downloadOnly=$INSTALL_downloadOnly"
}

###################################################
#start
###################################################
#记录安装的时间
start_time=`date --date='0 days ago' "+%Y-%m-%d %H:%M:%S"`
find $CUR_DIR/ -name "*.sh" | xargs chmod +x

#0.1, 参数解析
parse_args "$@"

#0.2 安装前提工具yq, 辅助解析配置文件，生成配置
install_yq

#1, 设置系统环境
! $INSTALL_downloadOnly && $bash_xc "$CUR_DIR/scripts/k8s-env.sh"

#2, 设置配置文件
pyellow "2, create configuration: /var/vke/node.yaml,k8s.conf"
$bash_xc "DOWNLOAD_ONLY=${INSTALL_downloadOnly} K8S_ha=${INSTALL_ha} $TOP_DIR/config/create-config.sh $CUR_DIR/config/package-${K8S_version}.yaml"

#eval $(cat $TOP_DIR/config/globalVars | grep -v "^#")
source $TOP_DIR/config/globalVars

#3, 安装软件，全部使用默认配置
pyellow "3, install binary "
install_pkgs $INSTALL_options
install_charts

#4，安装k8s-start, k8s-stop, k8s-rm等脚本
cp -rf $TOP_DIR/scripts/k8s-start.sh /usr/local/bin/k8s-start
sed -i "/^K8S_vkeConfigPath=.*/c K8S_vkeConfigPath=\${K8S_vkeConfigPath:-${K8S_vkeConfigPath}}" /usr/local/bin/k8s-start
cp -rf $TOP_DIR/scripts/k8s-stop.sh /usr/local/bin/k8s-stop
cp -rf $TOP_DIR/scripts/k8s-rm.sh /usr/local/bin/k8s-rm
chmod +x /usr/local/bin/k8s-start
chmod +x /usr/local/bin/k8s-stop
chmod +x /usr/local/bin/k8s-rm

mkdir -p /usr/lib/vke
cp -rf $TOP_DIR/scripts/utils.sh  /usr/lib/vke/


#5, start k8s, 读取配置, 启动服务
pyellow "5, start k8s"
if $INSTALL_startnow ; then
  bash $TOP_DIR/scripts/k8s-start.sh
else
  pyellow "startnow=false in /etc/vke/k8s.conf, i cann't start it, u can u up;"
  pyellow "use cmd: k8s-start"
fi
echo "Command usage: "
echo "   $(pyellow k8s-start): Read configuration file and execute 'kubeadm init' or 'kubeadm join'"
echo "   $(pyellow k8s-stop): Execute 'kubeadm reset -f' and delete Kubernetes-related files"
echo "   $(pyellow k8s-rm): Execute 'k8s-stop' and remove kubelet/kubeadm/kubectl, except for docker"


#计算总消耗时间
end_time=$(date --date="0 days ago" "+%Y-%m-%d %H:%M:%S")
duration=$(($(($(date +%s -d "$end_time")-$(date +%s -d "$start_time")))))
echo "install finished, start time $start_time, end time $end_time, duration $(($duration/60))'$(($duration%60))\""

